import 'dart:math';

import 'package:yl_kit/extension/yl_extension.dart';
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:yl_kit/src/yl_aes_encrypt.dart';

extension YLString on String {
  int toInt() => int.tryParse(this) ?? 0;
  double toDouble() => double.tryParse(this) ?? 0.0;

  List<String> toList({
    int? lengthSplit,
    Pattern? patternSplit,
  }) {
    late List<String> resultList = <String>[];
    if (lengthSplit != null) {
      final int length = this.length;
      if (lengthSplit == 0 || length < lengthSplit) {
        resultList = <String>[this];
      } else {
        final int remainder = length % lengthSplit;
        final int count = length ~/ lengthSplit;
        resultList = List<String>.generate(count, (int i) {
          final int start = i * lengthSplit;
          return substring(start, start + lengthSplit);
        }).toList();
        if (remainder != 0) {
          resultList.add(substring(length - remainder));
        }
      }
    } else {
      resultList = split(patternSplit ?? '');
    }
    return resultList;
  }

  List<String> splitAndTrim(pattern) {
    String text = this;
    final resultList = text.split(pattern);
    return resultList.trim();
  }

//是否是合法身份证
  bool get isIDCard {
    late bool result = false;

    if (isNotEmpty) {
      final RegExp regExp = RegExp(r'\d{17}[0-9Xx]$');
      if (regExp.hasMatch(this)) {
        final String forward17 = substring(0, 17);
        final String behind1 = substring(17).toUpperCase();
        final List<String> splitList = forward17.toList();
        // Coefficient for id.
        final List<String> modulusList =
            '7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2'.toList(patternSplit: ',');
        late int sum = 0;
        for (int i = 0; i < 17; i++) {
          final int item1 = int.parse(splitList[i]);
          final int item2 = int.parse(modulusList[i]);
          sum += item1 * item2;
        }
        final int remainder = sum % 11;
        late final Map<String, String> mapping = <String, String>{
          '0': '1',
          '1': '0',
          '2': 'X',
          '3': '9',
          '4': '8',
          '5': '7',
          '6': '6',
          '7': '5',
          '8': '4',
          '9': '3',
          '10': '2'
        };
        result = mapping[remainder.toString()] == behind1;
      }
    }
    return result;
  }

// 是否是手机号
  bool get isPhone => RegExp(
          r'^((13[^4]|14[5|7|9]|15[^4]|166|17[^0149]|18\d|19[^4])\d{8}|134[^9]\d{7})$')
      .hasMatch(this);
  // 是否是密码
  bool get isPwd =>
      RegExp(r'^(?=.*[0-9])(?=.*[a-zA-Z])(.{7,20})$').hasMatch(this);

  bool isRegular(String regular) => RegExp(regular).hasMatch(this);

  String toReplace(String replace, {String? regular}) {
    return (this).replaceAll(RegExp(regular ?? r'XXX'), replace);
  }

// 保留几位小数 省略末尾0
  String keepShortDigits(int length, {bool round = true}) {
    String allStr = (this).keepFractionDigits(length, round: round);
    List<String> nomreList = allStr.split('.');
    List numList = [];
    if (nomreList.length > 1) {
      List lastList = nomreList.last.toList().reversed.toList();
      for (var element in lastList) {
        if (element == '0' && numList.isEmpty) {
          continue;
        }
        numList.insert(0, element);
      }
    }
    return numList.isEmpty
        ? nomreList.first
        : "${nomreList.first}.${numList.join()}";
  }

//保留几位小数
  String keepFractionDigits(int length, {bool round = true}) {
    return round
        ? (this).toDouble().toStringAsFixed(length)
        : (this).toDouble().toYLPrecision(length).toString();
  }

// reverse
  String reverse() {
    String text = this;
    if (text.isEmpty) return "";
    StringBuffer sb = StringBuffer();
    for (int i = text.length - 1; i >= 0; i--) {
      sb.writeCharCode(text.codeUnitAt(i));
    }
    return sb.toString();
  }

  String encodePhone(
      {int start = 3, int end = 7, String replacement = '****'}) {
    String phone = this;
    if (phone.isPhone) {
      return phone.replaceRange(start, end, replacement);
    }
    return phone;
  }

  String encodeIdCard(
      {int start = 3, int end = 14, String replacement = '**** ****'}) {
    String idcard = this;
    if (idcard.isIDCard) {
      return idcard.replaceRange(start, end, replacement);
    }
    return idcard;
  }

  String formatSpace4() {
    String text = this;
    return text.formatDigitPattern();
  }

  bool isValidQueryString() {
    final RegExp regex = RegExp(
      r'^(?:\?|$)(?:[^=&?]+=[^=&?]*(?:&[^=&?]+=[^=&?]*)*)?$',
    );
    return regex.hasMatch(this);
  }

  String formatDoubleComma3({int digit = 3, String pattern = ','}) {
    String text = this;
    List<String> list = text.split('.');
    String left =
        list.first.formatDigitPatternEnd(digit: digit, pattern: pattern);
    String right = list[1];
    return '$left.$right';
  }

  String formatDigitPatternEnd({int digit = 4, String pattern = ' '}) {
    String text = this;
    String temp = text.reverse();
    temp = temp.formatDigitPattern(digit: digit, pattern: pattern);
    temp = temp.reverse();
    return temp;
  }

  String formatDigitPattern({int digit = 4, String pattern = ' '}) {
    String text = this;
    text = text.replaceAllMapped(RegExp('(.{$digit})'), (Match match) {
      return '${match.group(0)}$pattern';
    });
    if (text.endsWith(pattern)) {
      text = text.substring(0, text.length - 1);
    }
    return text;
  }

// 生成随机的字符串
  static String generateRandomString({int length = 16}) {
    final _random = Random();
    const _chars =
        'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
    return List.generate(length, (_) => _chars[_random.nextInt(_chars.length)])
        .join();
  }

  String toMd5() {
    String text = this;
    var bytes = utf8.encode(text); // 将字符串转换为UTF-8编码的字节列表
    var digest = md5.convert(bytes); // 计算MD5哈希值
    return digest.toString();
  }

  String toHash() {
    String text = this;
    var bytes = utf8.encode(text); // 将字符串转换为UTF-8编码的字节列表
    var digest = sha256.convert(bytes); // 计算SHA-1哈希值
    return digest.toString();
  }

  bool get isBase64 {
    // 正则表达式：检查字符范围和格式
    final pattern = RegExp(
      r'^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$',
    );
    return pattern.hasMatch(this);
  }

  String get filterText {
    String text = this;
    // 使用正则表达式删除括号及其内部内容
    return text.replaceAll(RegExp(r'（[^）]*）'), '');
  }

  String get aesCBCEncrypt {
    String value = this;
    try {
      return YLAESCBCEncrypt.instance.encrypter(value);
    } catch (e) {
      return value;
    }
  }

  String get aesCBCDecrypt {
    String value = this;
    try {
      if (value.isBase64) {
        return YLAESCBCEncrypt.instance.decrypter(value);
      }
      return value;
    } catch (e) {
      // 不是base64编码，直接返回原值
      return value;
    }
  }
}
